<?php
/**
 * Created by PhpStorm.
 * User: niqiaoyun
 * Date: 2017/9/5
 * Time: 10:25
 */

namespace app\controllers;


use app\common\widgets\Rbac;
use app\common\widgets\Tools;
use app\models\dao\RoleNav;
use app\models\dao\RoleNode;
use app\models\User;
use Yii;
use yii\base\Exception;
use yii\filters\AccessControl;
use yii\web\Controller;
use app\models\RoleModel;

class BaseController extends Controller {
	public $version = '';
	public $_limit = 20;
	public $pid;
	public $menu = array();
	public $shortcut_menu = array();
	public $menuColor = array();
	public $userType = 0;
	public $hotel_id = 0;

	public function init() {
		parent::init();
		$this->version = date('YmdHis');
		$this->view = \Yii::$app->view;
		$int_id = (int)\Yii::$app->user->getId();
		$ary_user = User::findIdentity($int_id);
		$this->view->params['username'] = $ary_user['username'];
		$this->view->params['id'] = $ary_user['username'];
		$pageSize = \Yii::$app->request->post('pageSize');
		$this->_limit = isset($pageSize) ? $pageSize : 20;

		//获取管理员所属权限组
		$ary_role = RoleModel::findOne(['id' => $ary_user['role_id'], ]);
		$this->view->params['role_name'] = $ary_role['name'];
	}

	public function beforeAction($action) {
		$controller = \Yii::$app->controller->id;
		$actionID = \Yii::$app->controller->action->id;
		$user_id = (int)\Yii::$app->user->getId();
		if(!\Yii::$app->user->isGuest) {
			$this->isAuth();
		}
		return parent::beforeAction($action);
	}

	public function leftMenu() {
		$roleNav = RoleNav::find()->where(['status' => 1, 'flag' => 1, 'type' => $this->userType])->orderBy('sort asc')->asArray()->all();
		if(!empty($roleNav)) {
			foreach($roleNav as &$nav) {
				$roleNode = RoleNode::find()->where(['nav_id' => $nav['id'], 'parent_id' => 0, 'status' => 1, 'flag' => 1, 'is_show' => 1, 'type' => $this->userType,])->orderBy('sort desc')->asArray()->all();
				if(!empty($roleNode)) {
					$nav['childMenu'] = $roleNode;

					foreach($nav['childMenu'] as $key=>&$node) {
						$nodeAccess = RoleNode::find()->where(['parent_id' => $node['id'], 'status' => 1, 'flag' => 1, 'is_show' => 1, 'type' => $this->userType,])->orderBy('sort desc')->asArray()->all();


						if(!empty($nodeAccess)) {
							$nav['childMenu'][$key]['childMenu'] = $nodeAccess;
						}
					}
				}
			}
		}
		$this->menu = $roleNav;
		$this->view->params['menus'] = $this->menu;
	}

	public function createMenu($paramsData) {
		$result = [];
		if(!empty($paramsData)) {
			foreach($paramsData as $key=>$menus) {
				$roleNav = RoleNav::find()->where(['status' => 1, 'flag' => 1, 'id' => $key, 'type' => $this->userType,])->orderBy('sort desc')->asArray()->one();
				if(!empty($roleNav)) {
					$result[$key] = $roleNav;
					foreach($menus as $ky=>$menu) {
						if(is_array($menu)) {
							foreach($menu as $k=>$mu) {

								$roleNode = RoleNode::find()->where(['nav_id' => $roleNav['id'], 'id' => $mu, 'parent_id' => 0, 'status' => 1, 'flag' => 1, 'is_show' => 1, 'type' => $this->userType,])->orderBy('sort desc')->asArray()->one();
								if(!empty($roleNode)) {
									$result[$key]['childMenu'][$roleNode['id']] = $roleNode;
									$nodeAccess = RoleNode::find()->where(['parent_id' => $roleNode['id'], 'id' => $k, 'status' => 1, 'flag' => 1, 'is_show' => 1, 'type' => $this->userType,])->orderBy('sort desc')->asArray()->one();

									$childMenu[] = $nodeAccess;
									if(!empty($nodeAccess)) {
										$result[$key]['childMenu'][$roleNode['id']]['childMenu'] = $childMenu;
									}
								}

							}

						} else {
							$roleNode = RoleNode::find()->where(['nav_id' => $roleNav['id'], 'id' => $menu, 'parent_id' => 0, 'status' => 1, 'flag' => 1, 'is_show' => 1, 'type' => $this->userType,])->orderBy('sort desc')->asArray()->one();
							$result[$key]['childMenu'][$roleNode['id']] = $roleNode;
						}
					}
				}

			}
		}
//		echo "<pre>";print_r($result);exit;
		if(!empty($result)) {
			//$result = Tools::arraySort($result, 'id', 'asc');
		}

//		$this->menu = $result;
		$this->menu = Tools::arraySort($result, 'sort', 'asc');
		$this->view->params['menus'] = $this->menu;
	}

	public function isAuth() {
		$pathInfo = \Yii::$app->getRequest()->pathInfo;

		$isAjax = \Yii::$app->getRequest()->isAjax;
		//获取当前用户可执行权限
		$user_id = (int)\Yii::$app->user->getId();

		$rbacObj = new Rbac($user_id);
		if(!$rbacObj::checkUserAccess()) {

			$accessArr = $rbacObj::accessDecision();
			if(!empty($accessArr['roleMenu'])) {
				$this->createMenu($accessArr['roleMenu']);
			}
			if(!empty($pathInfo)) {
				$roleNode = RoleNode::find($accessArr)->where(['url' => $pathInfo, 'flag' => 1, 'status' => 1, 'type' => $this->userType])->asArray()->one();

				if(!empty($roleNode)) {
//					echo "<pre>";print_r($accessArr);exit;
					if(!in_array($pathInfo, $accessArr['access_list'])) {
						if($isAjax) {
							Tools::sendJson("10000000", "暂无权限!");exit;
						} else {
							$this->nonPrivileged();exit;
						}

					}
				}

			}
		} else {
			$this->leftMenu();
		}
	}

	public function nonPrivileged() {
		$ary_page_data = [];
		echo $this->render('/site/non-privileged', $ary_page_data);
	}

	/**
	 * @inheritdoc
	 */
	public function behaviors() {
		return [
			'access' => [
				'class' => AccessControl::className(),
				'except'=>['login'],
				'rules' => [
					[
						'allow' => true,
						'roles' => ['@'],
					]
				],

			],

		];
	}

	/**
	 * 魔术方法 有不存在的操作的时候执行
	 * @access public
	 * @param string $method 方法名
	 * @param array $args 参数
	 * @return mixed
	 */
	public function __call($method, $args) {
		switch (strtolower($method)) {
			case '_get' : $input = & $_GET;
				break;
			case '_post' : $input = & $_POST;
				break;
			default:
				throw new Exception(__CLASS__ . ':' . $method . "您所请求的方法不存在");
		}
		if (!isset($args[0])) { // 获取全局变量
			$data = $input; // 由VAR_FILTERS配置进行过滤
		} elseif (isset($input[$args[0]])) { // 取值操作
			$data = $input[$args[0]];
			$filters = isset($args[1]) ? $args[1] : "htmlspecialchars";
			if ($filters) {// 2012/3/23 增加多方法过滤支持
				$filters = explode(',', $filters);
				foreach ($filters as $filter) {
					if (function_exists($filter)) {
						$data = is_array($data) ? array_map($filter, $data) : $filter($data); // 参数过滤
					}
				}
			}
		} else { // 变量默认值
			$data = isset($args[2]) ? $args[2] : NULL;
		}
		return $data;
	}

	public function success($str_message, $str_url) {
		//如果是异步请求
		if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
			echo json_encode(array('errno' => 0, 'error' => $str_message, 'url' => $str_url));
			exit;
		}

		echo $str_message;
		exit;
	}

	public function error($str_message, $str_url = '') {
		//如果是异步请求
		if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
			echo json_encode(array('errno' => 1, 'error' => $str_message, 'url' => $str_url));
			exit;
		}

		echo $str_message;
		exit;
	}


	/**
	 * Ajax方式返回数据到客户端
	 * @access protected
	 * @param mixed $data 要返回的数据
	 * @param String $type AJAX返回数据格式
	 * @return void
	 */
	public function ajaxReturn($data, $type = '') {
		if (empty($type))
			$type = 'JSON';
		if (strtoupper($type) == 'JSON') {
			// 返回JSON数据格式到客户端 包含状态信息
			header('Content-Type:text/html; charset=utf-8');
			exit(json_encode($data));
		} elseif (strtoupper($type) == 'XML') {
			// 返回xml格式数据
			header('Content-Type:text/xml; charset=utf-8');
			exit(xml_encode($data));
		} elseif (strtoupper($type) == 'EVAL') {
			// 返回可执行的js脚本
			header('Content-Type:text/html; charset=utf-8');
			exit($data);
		} else {
			// TODO 增加其它格式
		}
	}

	/**
	 * 记录日志
	 * @param string $module
	 * @param string $description
	 * @param array $requestParams
	 * @param array $responseParams
	 * @param string $method
	 * @param string $infoOrError
	 * @return array
	 */
	public static function newAddLog($module, $description, $requestParams = null, $responseParams = null, $method, $infoOrError = 'info')
	{
		$message = [
			'log_sub_type' => $module,
			'log_message' => $description,
			'request' => $requestParams,
			'method' => $method,
			'response' => $responseParams,
			'timespend' => '',
		];
		BaseController::addOrderLog($message, $infoOrError);
	}

	/**
	 *模块记录log
	 * @param array  $message   log信息
	$message = [
	'log_sub_type' => (string)'必须,pay',
	'log_message' => (array|string)'必须,具体log信息',
	'request' => (array|string)['选传,请求入参数'],
	'method' => (string)'选传,请求的接口方法名称包含相对路径(排除配置项中ip之后的路径);和request同时出现',
	'response' => (array|string)['选传,接口出参数'],
	'timespend' => (int)'选传,接口耗时',
	'api_address' => (string)'选传,调用第三方接口需要传值',
	];
	 * @param string $level     log级别
	 * @param string $category  log分类,默认application
	 */
	public static function addOrderLog($message = [], $level = 'info', $category = 'application')
	{
		switch ($level) {
			case 'info':
				Yii::info(json_encode($message), $category);
				break;
			case 'warning':
				Yii::warning(json_encode($message), $category);
				break;
			case 'error':
				Yii::error(json_encode($message), $category);
				break;
			default:
				Yii::trace(json_encode($message), $category);
				break;
		}
	}
}